package la.iok.hzsvn.lewin.movie.operation.service;

import la.iok.hzsvn.lewin.movie.core.model.FinancialAccountVo;
import la.iok.hzsvn.lewin.movie.operation.entity.FinancialAccount;
import la.iok.hzsvn.lewin.mybatis.service.BaseService;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;

import java.util.Collection;
import java.util.List;

public interface FinancialAccountService extends BaseService<FinancialAccount,Long> {
    /**
     * 充值
     * @param roomId 房间id.必须是有效值,方法内没有验证房间是否存在
     * @param amount 充值金额,单位为分
     */
    void charge(@Nullable Long roomId, @Nullable Integer amount);

    /**
     * 消费金额.必须包含id及金额和版本
     * @return 受影响的记录数,应该为1
     */
    int cost(@Nullable Long roomId, @Nullable Integer amount, @Nullable Long version);

    /**
     * 查询房间金融账号的余额
     * @param roomIds 房间id集合
     * @return 房间的金融账号
     */
    @NotNull
    @NotNullElement
    List<FinancialAccountVo> accounts(@Nullable Collection<Long> roomIds);

    /**
     * 查询房间的账号余额.如果房间id不为空,并且账号未找到,则创建一个余额为0的账号
     * @param roomId 房间id
     * @return 余额账号
     */
    @Nullable
    FinancialAccount account(@Nullable Long roomId);

    /**
     * 获取一个未计算过返利的账号
     * @param excludes 需要排除的账号id.有时候可能某些记录计算失败,此时会把它的状态还原，但是后续查询的时候需要过滤掉它，不然会一直失败
     * @param supportReturnMoneyRoomIds 支持返利的房间id。如果非空则只搜索指定的房间，如果为空，则搜索所有房间（此时主要用于单元测试，正常业务会提前判断为空抛出异常）
     * @return 获取的账号对象,此时对象returnMonth已经记录为当前月份
     */
    @Nullable
    FinancialAccount takeOneForReturn(@Nullable @NotNullElement Collection<Long> excludes, @NotNull @NotNullElement Collection<Long> supportReturnMoneyRoomIds);
    @Nullable
    List<FinancialAccount> takeForPreview(@Nullable @NotNullElement Collection<Long> excludes, @NotNull @NotNullElement Collection<Long> supportReturnMoneyRoomIds);

    /**
     * 恢复之前备份的返利月份
     * @param account 账号对象,记录了返利月份和返利月份备份
     * @return 修改的记录数,应该为1
     */
    int returnMonthBack(@Nullable FinancialAccount account);
}
